#![no_std]
#![no_main]
#![feature(allocator_api)]
#![feature(naked_functions)]
#![feature(vec_into_raw_parts)]
#![allow(dead_code)]
#![allow(unsafe_op_in_unsafe_fn)]
#![allow(unused_mut)]
#![allow(unused_variables)]

use core::hint::spin_loop;

extern crate alloc;

extern crate syscall;

mod acpi;
mod bus;
mod disk;
mod event;
mod fs;
mod malloc;
mod ulog;

pub fn addr_of<T>(reffer: &T) -> usize {
    reffer as *const T as usize
}

pub fn ref_to_mut<T>(reffer: &T) -> &mut T {
    unsafe { &mut *(addr_of(reffer) as *const T as *mut T) }
}

pub fn ref_to_static<T>(reffer: &T) -> &'static T {
    unsafe { &*(addr_of(reffer) as *const T) }
}

#[macro_export]
macro_rules! unsafe_trait_impl {
    ($struct: ident, $trait: ident) => {
        unsafe impl $trait for $struct {}
    };
    ($struct: ident, $trait: ident, $life: tt) => {
        unsafe impl<$life> $trait for $struct<$life> {}
    };
}

#[unsafe(no_mangle)]
extern "C" fn _start(acpi_rsdp: usize) -> ! {
    syscall::op::set_init_pid(syscall::op::getpid());

    ulog::init();

    acpi::init(acpi_rsdp);
    bus::pci::init();

    disk::init();

    fs::init();

    let self_proc_id = syscall::op::getpid();
    let request_fd = syscall::op::open(
        alloc::format!("/proc/{}", self_proc_id),
        syscall::op::OpenMode::ReadWrite,
    );

    loop {
        event::do_event(request_fd);
        spin_loop();
    }
}

#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
    log::error!("{}", info);
    syscall::op::exit(1)
}
